﻿// --------------------------------------------------------------------------------------------------------------------
// <summary>
//   The widget.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Widgets.MoviesForMyBlog
{
    using System;
    using System.Collections.Generic;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.IO;
    using System.Xml;
    using System.Text;
    using System.Text.RegularExpressions;
    using App_Code.Controls;

    /// <summary>
    /// The widget.
    /// </summary>
    public partial class Widget : WidgetBase
    {
        #region Properties

        public string dataSource = AppDomain.CurrentDomain.GetData("DataDirectory").ToString();

        //This is used to remove html formatting for text strings in tooltips
        public string strPattern = @"<(.|\n)*?>";

        //Declares all of the xmlnodes
        public XmlNodeList nodeMovieArt, nodeMovieTitle, nodeMoviesRated;
        public XmlNodeList nodeMoviesRatingPredicted, nodeMovieSynopsis, nodeMovieLink, nodeInstantPlayCount, nodeMovieCount;
        public XmlNode nodeInstant, nodeDVD, node;
        public XmlNode nodeParentInstant, nodeParentDVD;

        const int TRUNCATE_COUNT = 20;
        /// <summary>
        /// node - Album art
        /// node1 - Movie title
        /// nodeMovieRatings - Movie Links for Processing
        /// nodeMoviesRated - How the person Rated Movies
        /// nodeMoviesRatingPredicted - Predicted Rating for Movies
        /// TRUNCATE_COUNT - Provides the amount of text to truncate for movie display
        /// </summary>
        /// 
        public override bool IsEditable
        {
            get
            {
                return true;
            }
        }

        /// <summary>
        /// Gets the name. It must be exactly the same as the folder that contains the widget.
        /// </summary>
        /// <value></value>
        public override string Name
        {
            get
            {
                return "Movies For My Blog";
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// This method works as a substitute for Page_Load. You should use this method for
        /// data binding etc. instead of Page_Load.
        /// </summary>
        public override void LoadWidget()
        {
            if (!Page.IsPostBack || Session.IsNewSession)
            {
                Session["intMFMBCounter"] = 0;
                Session["strMFMBInstantDVD"] = "";
            }



            //This is the document for the movie data
            XmlDocument xmlDoc = new XmlDocument();
            //This is the XML documents for the user settings
            XmlDocument xmlDoc5 = new XmlDocument();

            if (File.Exists(dataSource + @"\moviesformyblognetflixdata.xml") && File.Exists(dataSource + @"\moviesformyblognetflixuser.xml"))
            {
                xmlDoc.Load(dataSource + @"\moviesformyblognetflixdata.xml");
                node = xmlDoc.SelectSingleNode("/data");

                //Verifies there has been some data added to the xml
                //This is required to ensure that all of the movies have not been filtered.
                if (node.SelectSingleNode("//InstantPlay").Attributes["id"].InnerText == "Full")
                {
                    nodeParentInstant = xmlDoc.SelectSingleNode("//InstantPlay/rental_history");
                }
                if (node.SelectSingleNode("//DiscsShipped").Attributes["id"].InnerText == "Full")
                {
                    nodeParentDVD = xmlDoc.SelectSingleNode("//DiscsShipped/rental_history");
                }

                //Load the user options xml data
                xmlDoc5.Load(dataSource + @"\moviesformyblognetflixuser.xml");
                XmlNode nodeTime = xmlDoc5.SelectSingleNode("//FilterSettings/DataRefresh/control[@id='time']");
                nodeInstant = xmlDoc5.SelectSingleNode("//DisplayQuantity/control[@id='InstantPlay']");
                nodeDVD = xmlDoc5.SelectSingleNode("//DisplayQuantity/control[@id='DiscsShipped']");

                if (Convert.ToBoolean(nodeInstant.Attributes["active"].InnerText) == false && Convert.ToBoolean(nodeDVD.Attributes["active"].InnerText) == false
                    || node.SelectSingleNode("//InstantPlay").Attributes["id"].InnerText == "Empty" && node.SelectSingleNode("//DiscsShipped").Attributes["id"].InnerText == "Empty")
                {
                    lblNodeCountErrorMsg.Text = "Please login as an Administrator and configure the Movies For My Blog plugin filters.";
                }
                else
                {
                    //This sets the default option selected as instant play if it is a new session
                    //based on the selections in the user options if they were included or not.
                    if (!Page.IsPostBack || Session.IsNewSession)
                    {
                        if (Convert.ToBoolean(nodeInstant.Attributes["active"].InnerText) == true &&
                            node.SelectSingleNode("//InstantPlay").Attributes["id"].InnerText != "Empty" &&
                            nodeParentInstant.ChildNodes.Count > 4)
                        {
                            Session["strMFMBInstantDVD"] = "InstantPlay";

                        }
                        else if (Convert.ToBoolean(nodeDVD.Attributes["active"].InnerText) == true &&
                                 node.SelectSingleNode("//DiscsShipped").Attributes["id"].InnerText != "Empty" &&
                            nodeParentDVD.ChildNodes.Count > 4)
                        {
                            Session["strMFMBInstantDVD"] = "DiscsShipped";

                        }

                    }

                    //Sets the node count based on the session variable
                    if ((string)Session["strMFMBInstantDVD"] == "InstantPlay")
                    {
                        lbDVD.Font.Bold = false;
                        lbInstantPlay.Font.Bold = true;
                        nodeMovieCount = xmlDoc.SelectNodes("//" + Session["strMFMBInstantDVD"].ToString() + "/rental_history/rental_history_item");
                    }
                    if ((string)Session["strMFMBInstantDVD"] == "DiscsShipped")
                    {
                        lbInstantPlay.Font.Bold = false;
                        lbDVD.Font.Bold = true;
                        nodeMovieCount = xmlDoc.SelectNodes("//" + Session["strMFMBInstantDVD"].ToString() + "/rental_history/rental_history_item");
                    }



                    DateTime dt1 = DateTime.Now;

                    //Check to see if data has been updated within 1 hour.
                    //The updates from netflix occur based on the refresh time setting
                    //It will also update if the file was newly created.
                    if (dt1.Subtract(File.GetLastWriteTime(dataSource
                        + @"\moviesformyblognetflixdata.xml")).TotalSeconds
                        > (Convert.ToInt32(nodeTime.Attributes["quantity"].InnerText) * 3600) || node.InnerText == "new")
                    {

                        MoviesForMyBlog mfmb = new MoviesForMyBlog();
                        mfmb.RefreshMovieData();
                        DisplayMoviesInfo();

                    }
                    else if (nodeMovieCount == null)
                    {
                        lblNodeCountErrorMsg.Text = "Please login as an Administrator and configure the Movies For My Blog plugin filters.";
                    }
                    else
                    {
                        DisplayMoviesInfo();
                    }
                }


            }
            else if (!File.Exists(dataSource + @"\moviesformyblognetflixdata.xml") || !File.Exists(dataSource + @"\moviesformyblognetflixuser.xml"))
            {
                lblFileExistErrorMsg.Text = "Please login as an Administrator and setup the Movies For My Blog plugin.";
            }
        }

        public void SetMovieData(int x)
        {
            lblMovieTitle.Text = nodeMovieTitle[x].Attributes["regular"].InnerText;

            Image1.ImageUrl = nodeMovieArt[x].Attributes["large"].InnerText;

            lblTitleSynopsis.Text = truncate(nodeMovieSynopsis[x].InnerText) + "...";
            //Used to remove Html tags that might exist in the movie tool tip
            Regex rgx = new Regex(strPattern);

            string tooltip = rgx.Replace(nodeMovieSynopsis[x].InnerText, string.Empty);
            lblTitleSynopsis.ToolTip = tooltip;


            //If it has been rated by user it display it
            //Otherwise it displays the predicted rating of the user.
            if (nodeMoviesRated[x].HasChildNodes)
            {
                if (nodeMoviesRated[x].FirstChild.Name == "user_rating")
                {
                    if (nodeMoviesRated[x].FirstChild.InnerText == "")
                    {
                        lblRating.Text = "Not Interested:";
                        int rating = 0;
                        double newrating = rating / 5 * 80;
                        mfmb_ratingdiv.Attributes.Add("Style", "Width: 80px; Height: 16px;  Background: url('pics/star.gif') repeat-x; background-position: 0px 0px;");
                        mfmb_ratingdiv.Attributes.Add("Title", rating.ToString() + " out of 5 stars");
                        mfmb_ratingdiv1.Attributes.Add("Style", "Width: " + newrating + "px; Height: 16px;  Background: url('pics/star.gif') repeat-x; background-position: 0px -16px;");


                    }
                    else
                    {
                        lblRating.Text = "I rated this:";
                        double rating = (Convert.ToDouble(nodeMoviesRated[x].ChildNodes[0].InnerText));
                        double newrating = rating / 5 * 80;
                        mfmb_ratingdiv.Attributes.Add("Style", "Width: 80px; Height: 16px;  Background: url('pics/star.gif') repeat-x; background-position: 0px 0px;");
                        mfmb_ratingdiv.Attributes.Add("Title", rating.ToString() + " out of 5 stars");
                        mfmb_ratingdiv1.Attributes.Add("Style", "Width: " + newrating + "px; Height: 16px;  Background: url('pics/star.gif') repeat-x; background-position: 0px -16px;");

                    }

                }
                else
                {
                    lblRating.Text = "Predicted Rating:";
                    double rating = (Convert.ToDouble(nodeMoviesRated[x].ChildNodes[0].InnerText));
                    double newrating = rating / 5 * 80;
                    mfmb_ratingdiv.Attributes.Add("Style", "Width: 80px; Height: 16px;  Background: url('pics/star.gif') repeat-x; background-position: 0px 0px;");
                    mfmb_ratingdiv.Attributes.Add("Title", rating.ToString() + " out of 5 stars");
                    mfmb_ratingdiv1.Attributes.Add("Style", "Width: " + newrating + "px; Height: 16px;  Background: url('pics/star.gif') repeat-x; background-position: 0px -16px;");

                }
            }
            else
            {
                lblRating.Text = "Predicted Rating:";
                double rating = (Convert.ToDouble(nodeMoviesRatingPredicted[x].InnerText));
                double newrating = rating / 5 * 80;
                mfmb_ratingdiv.Attributes.Add("Style", "Width: 80px; Height: 16px;  Background: url('pics/star.gif') repeat-x; background-position: 0px 0px;");
                mfmb_ratingdiv.Attributes.Add("Title", rating.ToString() + " out of 5 stars");
                mfmb_ratingdiv1.Attributes.Add("Style", "Width: " + newrating + "px; Height: 16px;  Background: url('pics/star.gif') repeat-x; background-position: 0px -16px;");

            }
        }
        public void DisplayMoviesInfo()
        {

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(dataSource + @"\moviesformyblognetflixdata.xml");

            nodeMovieArt = xmlDoc.SelectNodes("//" + Session["strMFMBInstantDVD"].ToString() + "/rental_history/rental_history_item/box_art");
            nodeMovieTitle = xmlDoc.SelectNodes("//" + Session["strMFMBInstantDVD"].ToString() + "/rental_history/rental_history_item/title");
            nodeMovieSynopsis = xmlDoc.SelectNodes("//" + Session["strMFMBInstantDVD"].ToString() + "/rental_history/rental_history_item/link/synopsis");
            nodeMoviesRated = xmlDoc.SelectNodes("//" + Session["strMFMBInstantDVD"].ToString() + "/ratings_user/ratings/ratings_item");
            nodeMoviesRatingPredicted = xmlDoc.SelectNodes("//" + Session["strMFMBInstantDVD"].ToString() + "/ratings_members/ratings/ratings_item/predicted_rating");
            nodeMovieLink = xmlDoc.SelectNodes("//" + Session["strMFMBInstantDVD"].ToString() + "/rental_history/rental_history_item/link[@title='web page']");

        }

        private string truncate(string originalInput)
        {
            return truncate(originalInput, TRUNCATE_COUNT);
        }

        private string truncate(string originalInput, int wordsLimit)
        {
            if (originalInput != null && originalInput != "")
            {
                //return originalInput.Length.ToString();
                StringBuilder output = new StringBuilder(originalInput.Length);
                StringBuilder input = new StringBuilder(originalInput);

                int words = 0;
                bool lastwasWS = true;
                int count = 0;

                do
                {
                    if (char.IsWhiteSpace(input[count]))
                    {
                        lastwasWS = true;
                    }
                    else
                    {
                        if (lastwasWS) words++;
                        lastwasWS = false;
                    }
                    output.Append(input[count]);
                    count++;
                } while ((words < wordsLimit || lastwasWS == false) && count < originalInput.Length);

                return output.ToString();
            }
            else
            {
                return string.Empty;
            }

        }

        protected void lbDVD_Click(object sender, EventArgs e)
        {
            Session["strMFMBInstantDVD"] = "DiscsShipped";
            Session["intMFMBCounter"] = 0;

            lbInstantPlay.Font.Bold = false;
            lbDVD.Font.Bold = true;
            DisplayMoviesInfo();

        }
        protected void lbInstantPlay_Click(object sender, EventArgs e)
        {
            Session["strMFMBInstantDVD"] = "InstantPlay";
            Session["intMFMBCounter"] = 0;

            lbDVD.Font.Bold = false;
            lbInstantPlay.Font.Bold = true;
            DisplayMoviesInfo();
        }
        #endregion
    }
}